# -*- coding = utf-8 -*-
# @Time：2022/3/1 11:29
# @Author：3ic
# @File：detect_num_hash.py
# @Software：PyCharm

import _thread
import multiprocessing
import sys

import win32con
import win32gui
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon, QIntValidator
from PyQt5.QtWidgets import QWidget, QLabel, QMessageBox, QCheckBox, QLineEdit

from control_switch import ControlSwitch
from iclogger import IcLogger

from stop_watch import StopWatch
from timeline_selector import TimelineSelector
from window_options import setForegroundWindowByWin32GUI, cap_hwnd, app

from instructor import Instructor
from executor import Executor


class IcBot:
    _logger = IcLogger('logs/icbot.logs')
    instructor = None
    executor = None

    def __init__(self):
        IcBot._logger.info('\n\n************* 启动软件 *************')
        try:
            # 生成基础界面
            self.ctrl_win = self._initBasicUi()
            # 设置控制组件
            self.stop_watch = StopWatch(self.ctrl_win, 20, 5)
            self.control_switch = ControlSwitch(self.ctrl_win, 20 + 140, 5)
            self.control_switch.bindSwitchOnResponse(self._startGameThread)
            self.control_switch.bindSwitchOffResponse(self._brakeGameThread)
            self.timeline_selector = TimelineSelector(self.ctrl_win)
            self.timeline_selector.moveComponents((5, 50), (5 + 75, 50), (5 + 75 + 105, 50))
            # 设置机器人的传参组件
            (self._scan_interval_textbox, self._auto_brake_checkbox, self._speedup_ub_checkbox,
             self._speedup_leisure_checkbox, self._speedup_rate_checkbox) = self.setParamComponent(self.ctrl_win)
        except BaseException as e:
            IcBot._logger.warning(e)

        self.ctrl_win.show()
        self.hwnd = win32gui.FindWindow('Qt5152QWindowIcon', 'icbot')
        sys.exit(app.exec_())

    def _initBasicUi(self):
        ctrl_win = QWidget()
        ctrl_win.setFixedSize(300, 150)
        ctrl_win.setWindowTitle('icbot')
        ctrl_win.setWindowIcon(QIcon('t.png'))

        about_label = QLabel(
            '作者：3ic&nbsp;&nbsp;' +
            '<a href="https://gitee.com/tripleice/ic-bot.git" style="color:#DDA0DD;">开源地址</a>'
            , ctrl_win)
        about_label.setAlignment(Qt.AlignHCenter)
        about_label.resize(300, 20)
        about_label.move(5, 130)
        about_label.setOpenExternalLinks(True)
        about_label.setStyleSheet('color:#DDA0DD;font-size:14px;font-weight:700;')

        return ctrl_win

    def setParamComponent(self, parent_window):
        scan_interval_label = QLabel('识别间隔(ms)：')
        scan_interval_label.resize(110, 25)
        scan_interval_label.move(15, 75 + 2)
        scan_interval_label.setStyleSheet('font-size:14px;')
        scan_interval_label.setParent(parent_window)

        scan_interval_textbox = QLineEdit('10')
        scan_interval_textbox.setAlignment(Qt.AlignHCenter)
        scan_interval_textbox.resize(30, 20)
        scan_interval_textbox.move(15 + 100, 75 + 5)
        scan_interval_textbox.setStyleSheet('font-size:14px;')
        scan_interval_textbox.setValidator(QIntValidator(1, 20))
        scan_interval_textbox.setParent(parent_window)

        auto_brake_checkbox = QCheckBox('自动暂停')
        auto_brake_checkbox.setChecked(True)
        auto_brake_checkbox.move(15 + 180, 80)
        auto_brake_checkbox.setStyleSheet('font-size:14px;')
        auto_brake_checkbox.setParent(parent_window)

        speedup_ub_checkbox = QCheckBox('加速ub')
        speedup_ub_checkbox.setChecked(False)
        speedup_ub_checkbox.move(15 + 100, 105)
        speedup_ub_checkbox.setStyleSheet('font-size:14px;')
        speedup_ub_checkbox.setParent(parent_window)

        speedup_leisure_checkbox = QCheckBox('加速空闲')
        speedup_leisure_checkbox.setChecked(False)
        speedup_leisure_checkbox.move(15, 105)
        speedup_leisure_checkbox.setStyleSheet('font-size:14px;')
        speedup_leisure_checkbox.setParent(parent_window)

        speedup_rate_checkbox = QCheckBox('上限4倍速')
        speedup_rate_checkbox.setChecked(False)
        speedup_rate_checkbox.move(15 + 100 + 80, 105)
        speedup_rate_checkbox.setStyleSheet('font-size:14px;')
        speedup_rate_checkbox.setParent(parent_window)

        return scan_interval_textbox, auto_brake_checkbox, speedup_ub_checkbox, speedup_leisure_checkbox, \
               speedup_rate_checkbox

    def _startGame(self):
        IcBot._logger.info('\n开始运行')
        try:
            # 调整当前窗口和雷电窗口的位置和布局
            setForegroundWindowByWin32GUI(cap_hwnd)
            win32gui.SetWindowPos(cap_hwnd, win32con.HWND_TOP, 0, 0, 1920, 1030, win32con.SWP_SHOWWINDOW)
            setForegroundWindowByWin32GUI(self.hwnd)

            # 准备管道
            # ---发令者给界面传 秒数信息 的管道、发令者给执令者传 执行任务 的管道
            time_point_pipe = multiprocessing.Pipe(False)
            sec_msg_pipe = multiprocessing.Pipe(False)
            # 准备轴
            timeline = self.timeline_selector.loadTimeLine()
            # 获取控制参数
            auto_brake = self._auto_brake_checkbox.isChecked()
            no_speedup_ub = not self._speedup_ub_checkbox.isChecked()
            speedup_mold = 3 if self._speedup_rate_checkbox.isChecked() else 2
            scan_interval = int(self._scan_interval_textbox.text()) / 1000
            speedup_leisure = self._speedup_leisure_checkbox.isChecked()

            # 创建机器人
            self.executor = Executor(time_point_pipe[0], auto_brake, no_speedup_ub, speedup_mold)
            self.instructor = Instructor(timeline, time_point_pipe[1], sec_msg_pipe[1], scan_interval, speedup_leisure)

            # 先准备好，再进入战斗
            self.stop_watch.start(sec_msg_pipe[0], )  # 监听时间信息
            self.executor.start()
            self.instructor.start()
            self.executor.doStarting()
            # 等待结束（发令者结束时会示意执令者和秒表结束）、暂停战斗
            self.executor.join()
            self.executor.doBraking()
            self.instructor.terminate()
            self.stop_watch.terminate()

            # 销毁机器人
            self.executor = None
            self.instructor = None

            # 强制关闭按钮
            self.control_switch.enforceToSwitchOff()
        except BaseException as e:
            IcBot._logger.warning(e)

    def _brakeGame(self):
        IcBot._logger.info('\n停止运行')
        try:
            # 制动战斗（让_startGame摆脱join的阻塞）
            if self.executor is not None:
                self.executor.terminate()
        except BaseException as e:
            IcBot._logger.warning(e)

    def _startGameThread(self):
        if self.timeline_selector.checkTimeline() is False:
            return False
        if self._scan_interval_textbox.text() == '':
            QMessageBox.critical(self._scan_interval_textbox.parentWidget(),
                                 '错误！', '识别间隔时间不能为空', QMessageBox.Ok, QMessageBox.Ok)
            return False
        _thread.start_new_thread(self._startGame, ())
        return True

    def _brakeGameThread(self):
        _thread.start_new_thread(self._brakeGame, ())
        return True


if __name__ == '__main__':
    # 打包指令（不带控制台）：pyinstaller -i t.ico -w icbot.py --hidden-import PyQt5.sip
    # 打包指令（带控制台）：pyinstaller -i t.ico icbot.py --hidden-import PyQt5.sip
    multiprocessing.freeze_support()
    if cap_hwnd == 0:
        QMessageBox.critical(QWidget(),
                             '错误！', '未检测到雷电模拟器', QMessageBox.Ok, QMessageBox.Ok)
        sys.exit()
    icbot = IcBot()
